Skip to main content

Kubernetes Deployment

This document describes the deployment of the SyncNow application on Kubernetes, including configuration, secrets, services, deployment, and ingress.


1. ConfigMap

syncnow-webapp-configmap
Stores web application configuration.

  • webconfig:
    {
    "apiEndpoint": "https://syncnowapp.example.com"
    }

2. Secrets

  • syncnow-db-password:
    Stores the database password (base64 encoded).

  • redis-password:
    Stores the Redis password (base64 encoded), redis is used for the AI.

  • ai-settings-secret:
    Stores the AI API key (base64 encoded), AI Key, we currently support Azure OpenAI


3. Service

syncnow-service

  • Type: ClusterIP
  • Port: 5030

4. Deployment

syncnow

  • Replicas: 1
  • Image: repo.example.com/syncnowserver:latest
  • Port: 5030
  • Liveness/Readiness Probes: /v1.0/Configuration/IsServiceReady
  • Volume: Mounts webconfig from ConfigMap to /WebApp/app.json
  • Image Pull Secret: imagepullsecret

Environment Variables

Refer to Environment Variables Configuration Parameters for all environment variables.

5. Volumes

  • syncnow-webapp-volume:
    Mounts the webconfig from the ConfigMap to /WebApp/app.json.

6. Ingress

syncnowingress

  • Host: SyncNowApp.example.com
  • TLS: Enabled (secret: syncnowsecret)
  • Service: syncnow-service:5030

7. Affinity

  • Pod anti-affinity ensures pods are distributed across nodes.

Notes

  • All secrets are base64 encoded.
  • Update secrets and config as needed for your environment.
  • Ensure image pull secrets are configured in your cluster.

Example

apiVersion: v1
kind: ConfigMap
metadata:
name: syncnow-webapp-configmap
labels:
app: syncnow
data:
webconfig: |
{
"apiEndpoint": "https://SyncNowApp.example.com"
}
---
apiVersion: v1
kind: Secret
metadata:
name: syncnow-db-password
labels:
app: syncnow
type: Opaque
data:
password: "REPLACE_BASE64_PASSWORD"
---
apiVersion: v1
kind: Secret
metadata:
name: redis-password
labels:
app: syncnow
type: Opaque
data:
password: "REPLACE_BASE64_PASSWORD"
---
apiVersion: v1
kind: Secret
metadata:
name: ai-settings-secret
labels:
app: syncnow
type: Opaque
data:
apikey: "REPLACE_BASE64_APIKEY"
---
apiVersion: v1
kind: Service
metadata:
name: syncnow-service
labels:
app: syncnow
spec:
type: ClusterIP
ports:
- port: 5030
targetPort: 5030
selector:
app: syncnow
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: syncnow
labels:
app: syncnow
spec:
replicas: 3
selector:
matchLabels:
app: syncnow
template:
metadata:
labels:
app: syncnow
spec:
containers:
- name: syncnow
image: repo.example.com/syncnowserver:latest
resources:
limits:
memory: "1024Mi"
ports:
- containerPort: 5030
imagePullPolicy: Always
securityContext:
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 999
livenessProbe:
httpGet:
path: /v1.0/Configuration/IsServiceReady
port: 5030
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /v1.0/Configuration/IsServiceReady
port: 5030
initialDelaySeconds: 5
periodSeconds: 10
volumeMounts:
- name: syncnow-webapp-volume
mountPath: /WebApp/app.json
subPath: webconfig
env:
- name: SETTINGS__TENANT
value: SyncNowApp
- name: SETTINGS__DATABASECONFIGURATION__DATABASETYPE
value: PostgreSQL
- name: SETTINGS__DATABASECONFIGURATION__SERVER
value: postgresql-dev1.example.com
- name: SETTINGS__DATABASECONFIGURATION__PORT
value: "5432"
- name: SETTINGS__DATABASECONFIGURATION__USERNAME
value: SyncNowUser
- name: SETTINGS__DATABASECONFIGURATION__PASSWORD
valueFrom:
secretKeyRef:
name: syncnow-db-password
key: password
- name: SETTINGS__DATABASECONFIGURATION__TRANSPORTENCRYPT
value: "False"
- name: SETTINGS__DATABASECONFIGURATION__DATABASE
value: SyncNowApp
- name: SETTINGS__CACHESTORECONFIGURATION__SERVER
value: "redis-stack.example.com"
- name: SETTINGS__CACHESTORECONFIGURATION__TIMEOUT
value: "60"
- name: SETTINGS__CACHESTORECONFIGURATION__PORT
value: "6379"
- name: SETTINGS__CACHESTORECONFIGURATION__USERNAME
value: ""
- name: SETTINGS__CACHESTORECONFIGURATION__PASSWORD
valueFrom:
secretKeyRef:
name: syncnow-db-password
key: password
- name: SETTINGS__VECTORDATABASECONFIGURATION__DATABASETYPE
value: "Redis"
- name: SETTINGS__VECTORDATABASECONFIGURATION__TIMEOUT
value: "60"
- name: SETTINGS__VECTORDATABASECONFIGURATION__SERVER
value: "redis-stack.example.com"
- name: SETTINGS__VECTORDATABASECONFIGURATION__URL
value: "redis-stack.example.com"
- name: SETTINGS__VECTORDATABASECONFIGURATION__PORT
value: "6379"
- name: SETTINGS__VECTORDATABASECONFIGURATION__USERNAME
value: ""
- name: SETTINGS__VECTORDATABASECONFIGURATION__PASSWORD
valueFrom:
secretKeyRef:
name: syncnow-db-password
key: password
- name: SETTINGS__AISETTINGS__ISAIACTIVE
value: "true"
- name: SETTINGS__AISETTINGS__CHATCOMPLETIONAIPROVIDER
value: "AzureOpenAI"
- name: SETTINGS__AISETTINGS__CHATCOMPLETIONMODELNAME
value: "gpt-4o-mini"
- name: SETTINGS__AISETTINGS__EMBEDDINGDEPLOYMENTNAME
value: "text-embedding-ada-002"
- name: SETTINGS__AISETTINGS__APIKEY
valueFrom:
secretKeyRef:
name: ai-settings-secret
key: apikey
- name: SETTINGS__AISETTINGS__PROVIDERURL
value: "https://ai-endpoint.cognitiveservices.azure.com/"
- name: ASPNETCORE_Environment
value: Development
- name: ASPNETCORE_URLS
value: http://*:5030
volumes:
- name: syncnow-webapp-volume
configMap:
name: syncnow-webapp-configmap
imagePullSecrets:
- name: imagepullsecret
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- syncnow
topologyKey: "kubernetes.io/hostname"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: syncnowingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "600m"
spec:
ingressClassName: nginx
tls:
- hosts:
- SyncNowApp.example.com
secretName: syncnowsecret
rules:
- host: SyncNowApp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: syncnow-service
port:
number: 5030